#ifndef GAMELOGIC_H
#define GAMELOGIC_H

#include "GameView.h"
#include "GamePhysics.h"
#include "GameProcessManager.h"
#include "Player.h"
#include "SaveTrigger.h"
#include "AttachedObjectUpdater.h"
#include "Level.h"

class GameLogic
{
public:
	GameLogic(void);
	~GameLogic(void);
	unsigned int nameCounter;
	bool init(GameView *view, bool loading = false);
	void reset(const bool rs = true);
	void update(const unsigned long elapsedTime);
	ObjectPtr createObject(const ObjectType type);
	void addObject(BaseObjectPtr object);
	GamePhysics *getPhysics(void) const;
	GameProcessManager *getProcessManager(void) const;
	const PlayerPtr getCharacter(void) const;
	const AttachedObjectUpdaterPtr getUpdatePairs(void) const;
	void addLevel(Level &lvl);
	Ogre::SceneNode *createParticleSystem(const Ogre::String script, Ogre::Vector3 &pos = Ogre::Vector3(0.0f, 0.0f, 0.0f), const bool leveldel = false);
	Ogre::SceneNode *createParticleSystem(const Ogre::String script, const unsigned long timeLength, Ogre::Vector3 &pos = Ogre::Vector3(0.0f, 0.0f, 0.0f));
	void removeParticleSystem(Ogre::SceneNode *node);
	void removeParticleSystem(Ogre::SceneNode *node, const unsigned long duration);
	// Save game progress in a save file
	void saveSaveGame(const float x, const float y, const float z, const bool spawn);
	void loadNextLevel(void);
private:
	// Load level from a file (need a parameter for filename)
	void loadLevel(const unsigned int level);
	// Load character from a file
	void loadCharacter(const bool reset);
	// Load game progress form a save file
	void loadSaveGame(void);
	// deletes all objects and lists
	void deleteGame(void);
	GameView *mpView;
	GamePhysics *mpPhysics;
	GameProcessManager *mpProcessMgr;
	PlayerPtr mpPlayer;
	SettingsManager *mpSaveFile;
	BaseObjectList mBaseObjectList;
	BaseObjectList mGravityObjectList;
	BaseObjectList mSnapToRailOnlyList;
	BaseTriggerList mBaseTriggerList;
	std::list<Ogre::SceneNode*> mParticleList;
	std::list<VisibleObjectPtr> mVisualList;
	AttachedObjectUpdaterPtr mpUpdatePairs;
	std::map<ObjectType, ObjectPtr> mCopyMap;
	bool mLoadSpawnPoint;
};

#endif